﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Hxsoft.AppV1.Module;
using Hxsoft.AppV1.WebUI;

namespace Hxsoft.AppV1._Controls
{
	public partial class Vote : Hxsoft.AppV1.UserControl
	{
		private LoadedValue<bool> loadedIsShowHeader;
		public bool IsShowHeader
		{
			get
			{
				if (loadedIsShowHeader.Loader == null)
					loadedIsShowHeader.Loader = () => BooleanExtensions.ConvertFromOrDefault(ViewState["IsShowHeader"], true);
				return loadedIsShowHeader.Value;
			}
			set
			{
				if (loadedIsShowHeader.Setter == null)
					loadedIsShowHeader.Setter = v => ViewState["IsShowHeader"] = v;
				loadedIsShowHeader.Value = value;
			}
		}

		private LoadedValue<string> loadedAction;
		public string Action
		{
			get
			{
				if (loadedAction.Loader == null)
					loadedAction.Loader = () => (string)ViewState["Action"];
				return loadedAction.Value;
			}
			set
			{
				if (loadedAction.Setter == null)
					loadedAction.Setter = v => ViewState["Action"] = v;
				loadedAction.Value = value;
			}
		}

		private LoadedValue<bool> loadedLoadDefaultAction;
		public virtual bool LoadDefaultAction
		{
			get
			{
				if (loadedLoadDefaultAction.Loader == null)
					loadedLoadDefaultAction.Loader = () => BooleanExtensions.ConvertFromOrDefault(ViewState["LoadDefaultAction"], false);
				return loadedLoadDefaultAction.Value;
			}
			set
			{
				if (loadedLoadDefaultAction.Setter == null)
					loadedLoadDefaultAction.Setter = v => ViewState["LoadDefaultAction"] = v;
				loadedLoadDefaultAction.Value = value;
			}
		}

		private LoadedValue<bool> loadedAlwayShowForm;
		public virtual bool AlwayShowForm
		{
			get
			{
				if (loadedAlwayShowForm.Loader == null)
					loadedAlwayShowForm.Loader = () => BooleanExtensions.ConvertFromOrDefault(ViewState["AlwayShowForm"], false);
				return loadedAlwayShowForm.Value;
			}
			set
			{
				if (loadedAlwayShowForm.Setter == null)
					loadedAlwayShowForm.Setter = v => ViewState["AlwayShowForm"] = v;
				loadedAlwayShowForm.Value = value;
			}
		}

		private string ActionAttribute
		{
			get
			{
				string action = Action;
				if (string.IsNullOrEmpty(action) && LoadDefaultAction)
				{
					action = GenericUrlManager.BuildVoteDetailUrl(VoteClass.ClassCode, VoteContent.VoteId);
				}
				return string.IsNullOrEmpty(action) ? "" : @" action=""" + action + @"""";
			}
		}

		private LoadedValue<string> loadedTarget;
		public string Target
		{
			get
			{
				if (loadedTarget.Loader == null)
					loadedTarget.Loader = () => (string)ViewState["Target"];
				return loadedTarget.Value;
			}
			set
			{
				if (loadedTarget.Setter == null)
					loadedTarget.Setter = v => ViewState["Target"] = v;
				loadedTarget.Value = value;
			}
		}

		private string TargetAttribute
		{
			get
			{
				return string.IsNullOrEmpty(Target) ? "" : @" target=""" + Target + @"""";
			}
		}
		
		private LoadedValue<Module.Vote> loadedVoteContent;
		public Module.Vote VoteContent
		{
			get
			{
				if (loadedVoteContent.Loader == null)
					loadedVoteContent.Loader = () => (Module.Vote)ViewState["VoteContent"];
				return loadedVoteContent.Value;
			}
			set
			{
				if (loadedVoteContent.Setter == null)
					loadedVoteContent.Setter = v => ViewState["VoteContent"] = v;
				loadedVoteContent.Value = value;
			}
		}

		private LoadedValue<Module.VoteClass> loadedVoteClass;
		public Module.VoteClass VoteClass
		{
			get
			{
				if (loadedVoteClass.Loader == null)
					loadedVoteClass.Loader = () => Module.VoteClasses.GetItem(VoteContent.ClassId);
				return loadedVoteClass.Value;
			}
		}

		private LoadedValue<VoteViewType> loadedViewType;
		public VoteViewType ViewType
		{
			get
			{
				if (loadedViewType.Loader == null)
					loadedViewType.Loader = () => EnumExtensions.ConvertFromOrDefault<VoteViewType>(ViewState["ViewType"], VoteViewType.VoteForm);
				return loadedViewType.Value;
			}
			set
			{
				if (loadedViewType.Setter == null)
					loadedViewType.Setter = v => ViewState["ViewType"] = v;
				loadedViewType.Value = value;
			}
		}

		private LoadedValue<string> loadedVoteViewUrl;
		public string VoteViewUrl
		{
			get
			{
				if (loadedVoteViewUrl.Loader == null)
					loadedVoteViewUrl.Loader = () => (string)ViewState["VoteViewUrl"];
				return string.IsNullOrEmpty(loadedVoteViewUrl.Value) ? GenericUrlManager.BuildVoteDetailUrl(VoteViewType.VoteView, VoteClasses.GetItem(VoteContent.ClassId).ClassCode, VoteContent.VoteId) : loadedVoteViewUrl.Value;
			}
			set
			{
				if (loadedVoteViewUrl.Setter == null)
					loadedVoteViewUrl.Setter = v => ViewState["VoteViewUrl"] = v;
				loadedVoteViewUrl.Value = value;
			}
		}




		private const string VoteHistoryKey = "VoteHistory";
		protected string Process()
		{
			// 过期
			var now = DateTime.Now;
			if (!AlwayShowForm && (VoteContent.ReleaseDate > now || VoteContent.ExpirationDate < now))
				return GetViewHtml();

			var cookie = Request.Cookies[VoteHistoryKey];
			int[] cookieValues = null;
			if (cookie != null && !string.IsNullOrEmpty(cookie.Value))
			{
				cookieValues = Hxsoft.StringExtensions.Decompound<int>(cookie.Value, ",", StringSplitOptions.RemoveEmptyEntries);
				if (cookieValues != null && cookieValues.Contains(VoteContent.VoteId))
					return AlwayShowForm ? GetFormHtml() : GetViewHtml();
			}

			if (ViewType == VoteViewType.VoteView)
				return GetViewHtml();

			if(!Votes.GetVoteRight(VoteContent, false))
				return GetViewHtml();

			// 进行调查
			int? voteId = IntExtensions.ParseOrNull(Request.Form["VoteId"]);
			if (voteId.HasValue && VoteContent.VoteId == voteId.Value)
			{
				string strVoteItem = Request.Form["VoteItem"];
				int[] voteItems = Hxsoft.StringExtensions.Decompound<int>(strVoteItem, ",", StringSplitOptions.RemoveEmptyEntries);
				string userDefinedContent = Request.Form["UserDefinedContent"];
				if ((voteItems != null && voteItems.Length > 0) || !string.IsNullOrEmpty(userDefinedContent))
				{
					// 需要填写联系信息表单
					string name = null;
					string telephone = null;
					if (VoteContent.NeedContactInfo)
					{
						name = Request.Form["Name"];
						telephone = Request.Form["Telephone"];
						string html = GetContactFormHtml(voteId.Value, strVoteItem, userDefinedContent, name, telephone);
						if (!string.IsNullOrEmpty(html))
							return html;
					}

					VoteResult result = new VoteResult();
					result.Ip = Request.UserHostAddress;
					result.SelectedIndexs = voteItems;
					result.UserDefinedContent = userDefinedContent;
					result.VoteId = voteId.Value;
					result.Name = name;
					result.Telephone = telephone;
					result = Votes.Vote(result);
					VoteContent = Votes.GetItem(result.VoteId);

					List<int> cookieValueList = new List<int>();
					if (cookieValues != null) cookieValueList.AddRange(cookieValues);
					cookieValueList.Add(voteId.Value);
					Response.Cookies[VoteHistoryKey].Value = Hxsoft.StringExtensions.Compound<int>(cookieValueList, ",");

					return GetViewHtml();
				}
			}

			return GetFormHtml();
		}

		protected string GetViewHtml()
		{
			StringBuilder html = new StringBuilder();

			html.AppendLine(@"<table class=""VoteTable"">");

			if (IsShowHeader)
			{
				html.AppendLine(@"<tr>");
				html.AppendLine(@"	<th class=""VoteIndex"">序号</td>");
				html.AppendLine(@"	<th class=""VoteTitle"">标题</td>");
				html.AppendLine(@"	<th class=""VoteRatio"">比例</td>");
				html.AppendLine(@"	<th class=""VoteCount"">票数</td>");
				html.AppendLine(@"</tr>");
			}

			for (int i = 1; i <= VoteContent.VoteItemList.Count; i++)
			{
				VoteItem item = VoteContent.VoteItemList[i - 1];
				double percent = (VoteContent.VoteCount == 0 ? 0 : (double)item.VoteCount / VoteContent.VoteCount * 100);
				percent = Math.Round(percent, 2);

				html.AppendLine(@"<tr>");
				html.AppendLine(@"	<td class=""VoteIndex"">" + i + @"</td>");
				html.AppendLine(@"	<td class=""VoteTitle"">" + item.OptionTitle + @"</td>");
				html.AppendLine(@"	<td class=""VoteRatio""><span class=""percent_bg""><span style=""width:" + percent + @"%"" class=""percent""><span class=""percentText"">" + percent + "%</span>&nbsp;</span></span></td>");
				html.AppendLine(@"	<td class=""VoteCount"">" + item.VoteCount + @"</td>");
				html.AppendLine(@"</tr>");
			}

			if (VoteContent.UserDefinedCount > 0)
			{
				double percent = (VoteContent.VoteCount == 0 ? 0 : (double)VoteContent.UserDefinedCount / VoteContent.VoteCount * 100);
				percent = Math.Round(percent, 2);

				html.AppendLine(@"<tr>");
				html.AppendLine(@"	<td class=""VoteIndex""></td>");
				html.AppendLine(@"	<td class=""VoteTitle"">" + VoteContent.UserDefinedTitle + @"</td>");
				html.AppendLine(@"	<td class=""VoteRatio""><span class=""percent_bg""><span style=""width:" + percent + @"%"" class=""percent""><span class=""percentText"">" + percent + "%</span>&nbsp;</span></span></td>");
				html.AppendLine(@"	<td class=""VoteCount"">" + VoteContent.UserDefinedCount + @"</td>");
				html.AppendLine(@"</tr>");
			}

			html.AppendLine(@"<tr>");
			html.AppendLine(@"	<td class=""VoteIndex""></td>");
			html.AppendLine(@"	<td class=""VoteTitle""></td>");
			html.AppendLine(@"	<td class=""VoteRatio""></td>");
			html.AppendLine(@"	<td class=""VoteCount"">" + VoteContent.VoteCount + @"</td>");
			html.AppendLine(@"</tr>");

			html.AppendLine("</table>");

			// 过期显示获奖名单
			if (VoteContent.ExpirationDate < DateTime.Now)
			{
				GenericModuleDataContext dc = new GenericModuleDataContext();
				var q = from p in dc.VoteResults
						where p.VoteId == VoteContent.VoteId && p.IsAward == true
						select new { p.Name, p.AwardContent };
				if (q.Count() > 0)
				{
					html.AppendLine(@"<div class=""VoteAward"">");
					html.AppendLine(@"<div class=""awardTitle"">获奖名单：</div>");
					html.AppendLine(@"<ul class=""awardList"">");
					foreach (var item in q)
						html.AppendLine(@"	<li>" + item.Name + (string.IsNullOrEmpty(item.AwardContent) ? "" : "：" + item.AwardContent) + "</li>");
					html.AppendLine(@"</ul>");
					html.AppendLine(@"</div>");
				}
			}

			return html.ToString();
		}

		protected const int FORMTYPE_CONTACT = 1;
		protected string GetContactFormHtml(int voteId, string voteItem, string userDefinedContent, string name, string telephone)
		{
			int? formType = IntExtensions.ParseOrNull(Request.Form["FormType"]);
			string errMsg_name = null;
			string errMsg_telephone = null;
			if (formType == FORMTYPE_CONTACT)
			{
				bool isErr = false;
				if (string.IsNullOrEmpty(name))
				{
					isErr = true;
					errMsg_name = "姓名不允许为空。";
				}
				if (string.IsNullOrEmpty(telephone))
				{
					isErr = true;
					errMsg_telephone = "电话不允许为空。";
				}
				if (!isErr)
					return null;
			}

			StringBuilder html = new StringBuilder();

			html.AppendLine("<form id=\"" + this.ClientID + "\"" + TargetAttribute + ActionAttribute + @" method=""post"">");
			html.AppendLine(@"<input type=""hidden"" name=""FormType"" value=""" + FORMTYPE_CONTACT + @""" />");
			html.AppendLine(@"<input type=""hidden"" name=""VoteId"" value=""" + voteId + @""" />");
			html.AppendLine(@"<input type=""hidden"" name=""VoteItem"" value=""" + HttpUtility.HtmlEncode(voteItem) + @""" />");
			html.AppendLine(@"<input type=""hidden"" name=""UserDefinedContent"" value=""" + HttpUtility.HtmlEncode(userDefinedContent) + @""" />");
			html.AppendLine(@"<table class=""VoteContactTable"">");

			html.AppendLine(@"<tr>");
			html.AppendLine(@"	<td colspan=""2"" class=""fieldTip"">为便于抽奖，请留下您的联系方式。</td>");
			html.AppendLine(@"</tr>");
			html.AppendLine(@"<tr>");
			html.AppendLine(@"	<td class=""fieldTitle"">姓名</td>");
			html.AppendLine(@"	<td class=""fieldInput""><input type=""text"" name=""Name"" value=""" + HttpUtility.HtmlEncode(name) + @"""><span class=""error"">" + errMsg_name + @"</span></td>");
			html.AppendLine(@"</tr>");
			html.AppendLine(@"<tr>");
			html.AppendLine(@"	<td class=""fieldTitle"">电话</td>");
			html.AppendLine(@"	<td class=""fieldInput""><input type=""text"" name=""Telephone"" value=""" + HttpUtility.HtmlEncode(telephone) + @"""><span class=""error"">" + errMsg_telephone + @"</span></td>");
			html.AppendLine(@"</tr>");

			html.AppendLine("</table>");
			html.AppendLine(string.Format(@"<div class=""VoteSubmitBar""><input class =""{0}"" type=""submit"" value=""提交"" /> <input  class =""{1}"" type=""reset"" value=""重置"" />", SubmitClass, ResetClass));
			html.AppendLine("</form>");

			return html.ToString();
		}
		
		protected string GetFormHtml()
		{
			StringBuilder html = new StringBuilder();

			html.AppendLine("<form id=\"" + this.ClientID + "\"" + TargetAttribute + ActionAttribute + @" method=""post"">");
			html.AppendLine(@"<input type=""hidden"" name=""VoteId"" value=""" + VoteContent.VoteId + @""" />");
			html.AppendLine(@"<table class=""VoteTable"">");

			if (IsShowHeader)
			{
				html.AppendLine(@"<tr>");
				html.AppendLine(@"	<th class=""VoteIndex"">序号</td>");
				html.AppendLine(@"	<th class=""VoteInput""></td>");
				html.AppendLine(@"	<th class=""VoteTitle"">标题</td>");
				html.AppendLine(@"</tr>");
			}

			for (int i = 1; i <= VoteContent.VoteItemList.Count; i++)
			{
				VoteItem item = VoteContent.VoteItemList[i - 1];

				html.AppendLine(@"<tr>");
				html.AppendLine(@"	<td class=""VoteIndex"">" + i + @"</td>");
				html.AppendLine(@"	<td class=""VoteInput""><input type=""" + (VoteContent.IsMultiSelect ? "checkbox" : "radio") + @""" name=""VoteItem"" value=""" + i + @"""></td>");
				html.AppendLine(@"	<td class=""VoteTitle"">" + item.OptionTitle + @"</td>");
				html.AppendLine(@"</tr>");
			}

			if (!string.IsNullOrEmpty(VoteContent.UserDefinedTitle))
			{
				html.AppendLine(@"<tr>");
				html.AppendLine(@"	<td class=""VoteIndex""></td>");
				html.AppendLine(@"	<td class=""VoteInput""><input id=""OtherVoteItem_" + this.ClientID + @""" type=""" + (VoteContent.IsMultiSelect ? "checkbox" : "radio") + @""" name=""VoteItem"" value="""" onclick=""" + this.ClientID + @"_ChangeTextareaState();""></td>");
				html.AppendLine(@"	<td class=""VoteTitle"">" + VoteContent.UserDefinedTitle + @"</td>");
				html.AppendLine(@"</tr>");

				html.AppendLine(@"<tr>");
				html.AppendLine(@"	<td class=""VoteIndex""></td>");
				html.AppendLine(@"	<td class=""VoteInput""></td>");
				html.AppendLine(@"	<td class=""VoteTitle""><textarea id=""UserDefinedContent_" + this.ClientID + @""" name=""UserDefinedContent"" class=""VoteUserDefinedContent"" disabled=""disabled""></textarea></td>");
				html.AppendLine(@"</tr>");
			}

			html.AppendLine("</table>");
			html.AppendLine(string.Format(@"<div class=""VoteSubmitBar""><input class =""{0}"" type=""submit"" value=""投票"" /> <input  class =""{1}"" type=""reset"" value=""重置"" /> <a  class =""{2}"" href=""{3}""  {4}>查看调查结果</a></div>", SubmitClass, ResetClass, ViewClass,VoteViewUrl,TargetAttribute));
			html.AppendLine("</form>");

			html.AppendLine(@"<script type=""text/javascript"">");
			html.AppendLine(@"function " + this.ClientID + @"_ChangeTextareaState() { document.getElementById(""UserDefinedContent_" + this.ClientID + @""").disabled = !document.getElementById(""OtherVoteItem_" + this.ClientID + @""").checked; }");
			html.AppendLine(@"</script>");

			return html.ToString();
		}

		private LoadedValue<string> loadedSubmitClass;
		public string SubmitClass
		{
			get {
				if (loadedSubmitClass.Loader == null)
					loadedSubmitClass.Loader = () => (string)ViewState["SubmitClass"];
				return loadedSubmitClass.Value;
			}
			set {
				if (loadedSubmitClass.Setter == null)
					loadedSubmitClass.Setter = v => ViewState["SubmitClass"] = v;
				loadedSubmitClass.Value = value;
			}
		}

		private LoadedValue<string> loadedResetClass;
		public string ResetClass
		{
			get
			{
				if (loadedResetClass.Loader == null)
					loadedResetClass.Loader = () => (string)ViewState["ResetClass"];
				return loadedResetClass.Value;
			}
			set
			{
				if (loadedResetClass.Setter == null)
					loadedResetClass.Setter = v => ViewState["ResetClass"] = v;
				loadedResetClass.Value = value;
			}
		}

		private LoadedValue<string> loadedViewClass;
		public string ViewClass
		{
			get
			{
				if (loadedViewClass.Loader == null)
					loadedViewClass.Loader = () => (string)ViewState["ViewClass"];
				return loadedViewClass.Value;
			}
			set
			{
				if (loadedViewClass.Setter == null)
					loadedViewClass.Setter = v => ViewState["ViewClass"] = v;
				loadedViewClass.Value = value;
			}
		}






		protected override void OnPreRender(EventArgs e)
		{
			this.ApplicationPage.RegisterHeadIncludeFile(ApplicationConfiguration.VoteFolderUrl + "/C.css", IncludeFileType.CSS);

			base.OnPreRender(e);
		}
	}
}